<?php

class form {
	private $aether;
	private $name;
	private $model = false;
	private $data;
	private $inlineErrors;

	function __construct($name, $data, $aether, $args = array()) {
		$this->name = $name;
		$this->aether = $aether;
		$this->h = $aether->helpers;
		$args = arrayExtend($args, array(
			'method' => 'post',
			'action' => $this->aether->getRawUrl(),
			'model' => $name,
			'inlineErrors' => false
		));
		$this->args = $args;
		$this->data = $data;

		if($args['model']) {
			$model = $args['model'];
			$this->model = $this->aether->models->$model;
		}
	}

	function setData($data) {
		$this->data = $data;
	}
	
	function open($attr = array()) {
		$attr = arrayExtend($attr, array(
			'method' => $this->args['method'],
			'action' => $this->args['action']
		));
			
		return $this->h->html->open('form', $attr);
	}
	
	function close() {
		return $this->h->html->close();
	}

	function generateName($name, $indexes = array()) {
		$return = $this->name . '['.$name.']';
		foreach($indexes as $index) {
			if($index=='*') {
				if(!isset($this->curIndex[$name])) {
					$this->curIndex[$name] = 0;
				}
				$return .= '['.$this->curIndex[$name].']';
			} else {
				$return .= '['.$index.']';
			}
		}
		return $return;
	}

	var $curIndex = array();

	function generateId($name, $indexes = array()) {
		$return = $this->name . '-' . $name;
		foreach($indexes as $index) {
			if($index!='*') {
				$return .= '-' . $index;
			} else {
				$return .= '-' . $this->curIndex[$name];
				$this->curIndex[$name]++;
			}
		}
		return $return;
	}

	function getData($name, $indexes = array()) {
		if(is_object($name)) {
			$data = $name;
		} else if($this->data->hasChild($name)) {
			$data = $this->data->child($name);
		} else {
			return new data();
		}

		foreach($indexes as $key => $index) {
			if($index=='*') {
				$return = array();
				$newIndexes = array_slice($indexes, $key+1);
				$list = $data->listChildren();
				foreach($list as $child) {
					$return = arrayAppend($return, $this->getData($child, $newIndexes));
				}
				$return = newData($return);
				$return->setValidated($data->validated());
				$return->setErrors($data->getErrors());
				return $return;
			} else if($data->hasChild($index)) {
				$data = $data->child($index);
			} else {
				return new data();
			}
		}

		return $data;
	}

	function label($for, $label, $error) {
		$attr = array('for' => $for);
		if($error) {
			$attr['class'] = array('error');
		}
		return $this->h->html->open('label', $attr, array('content' => $label));
	}
/*
	private function hasError($name, $indexes = array()) {
		$find = false;
		if(isset($this->model->errors[$name])) {
			$find = $this->model->errors[$name];
			foreach($indexes as $index) {
				
		if($this->model&&isset($this->model->errors[$name])) {
			return true;
		} else {
			return false;
		}
	}
*/	
	function text($name, $args = array(), $attr = array()) {
		$args = arrayExtend($args, array(
			'indexes' => array(),
			'password' => false,
			'inheritValue' => true
		));

		$attr = arrayExtend($attr, array(
			'name' => $this->generateName($name, $args['indexes']),
			'id' => $this->generateId($name, $args['indexes']),
			'class' => array()
		));
		
		if($args['password']) {
			$attr['type'] = 'password';
			$attr['class'] = arrayAppend($attr['class'], array('password'));
		} else {
			$attr['type'] = 'text';
			$attr['class'] = $attr['class'] = $attr['class'] = $attr['class'] = $attr['class'] = $attr['class'] = $attr['class'] = $attr['class'] = $attr['class'] = arrayAppend($attr['class'], array('text'));
		}

		$data = $this->getData($name, $args['indexes']);
		if($args['inheritValue']&&$data->getValue()) {
			$attr['value'] = $data->getValue();
		} else if(isset($args['value'])) {
			$attr['value'] = $args['value'];
		}

		$error = false;
		if($data->hasErrors()) {
			$error = true;
			$attr['class'] = arrayAppend($attr['class'], array('error'));
		}
		
		//Create tag
		$return = $this->h->html->open('input', $attr, array('selfClosing' => true));
		if(isset($args['label'])) {
			$return = $this->label($attr['id'], $args['label'], $error) . $return;
		}
		if($error) {
			$return .= $this->inlineErrors($data);
		}

		return $return;
	}

	function textarea($name, $args = array(), $attr = array()) {
		$args = arrayExtend($args, array(
			'indexes' => array(),
			'inheritValue' => true
		));

		$attr = arrayExtend($attr, array(
			'name' => $this->generateName($name, $args['indexes']),
			'id' => $this->generateId($name, $args['indexes']),
			'class' => array()
		));
		
		$data = $this->getData($name, $args['indexes']);
		if($args['inheritValue']&&$data->getValue()) {
			$content = $data->getValue();
		} else if(isset($args['value'])) {
			$content = $args['value'];
		} else {
			$content = '';
		}

		$error = false;
		if($data->hasErrors()) {
			$error = true;
			$attr['class'] = arrayAppend($attr['class'], array('error'));
		}
		
		//Create tag
		$return = $this->h->html->open('textarea', $attr, array('content' => $content));
		if(isset($args['label'])) {
			$return = $this->label($attr['id'], $args['label'], $error) . $return;
		}
		if($error) {
			$return .= $this->inlineErrors($data);
		}

		return $return;
	}

	function password($name, $args = array()) {
		$args = arrayExtend($args, array(
			'inheritValue' => false,
			'password' => true
		));
		return $this->text($name, $args);
	}

	function checkbox($name, $args = array()) {
		$args = arrayExtend($args, array(
			'checked' => false,
			'inheritValue' => true,
			'checked' => false,
			'value' => 1,
			'indexes' => array()
		));
		$attr = array(
			'type' => 'checkbox',
			'value' => $args['value'],
			'name' => $this->generateName($name, $args['indexes']),
			'id' => $this->generateId($name, $args['indexes']),
			'class' => array('checkbox')
		);
		
		$data = $this->getData($name, $args['indexes']);
		if($args['inheritValue']&&is_object($data)) {
			foreach($data->listChildren() as $child) {
				if($child->getValue()==$args['value']) {
					$attr['checked'] = true;
					$data = $child;
					break;
				}
			}
			if(is_array($data)) {
				$data = new data();
			}
			if(!isset($attr['checked'])) {
				$data = new data();
			}
		} else if($args['inheritValue']&&$data->getValue()) {
			$attr['checked'] = true;
		} else if($args['checked']) {
			$attr['checked'] = true;
		}

		if($data->hasErrors()) {
			$error = true;
			$attr['class'] = arrayAppend($attr['class'], array('error'));
		} else {
			$error = false;
		}

		$return = $this->h->html->open('input', $attr, array('selfClosing' => true));
		if(isset($args['label'])) {
			$return .= $this->label($attr['id'], $args['label'], $error);
		}
		if($error) {
			$return .= $this->inlineErrors($data);
		}
		return $return;
	}

	function checkboxGroup($name, $boxes, $args = array()) {
		$return = '';
		if(isset($args['label'])) {
			$return .= $args['label'];
		}

		$args = arrayExtend($args, array(
			'indexes' => array()
		));

		$data = $this->getData($name, $args['indexes']);
		if($data->hasErrors()) {
			$return .= $this->inlineErrors($data);
		}

		$return .= $this->h->html->open('ul');	

		foreach($boxes as $box) {
			$box = arrayExtend($box, array(
				'liAttr' => array(),
				'indexes' => $args['indexes']
			));

			$return .= $this->h->html->open('li', $box['liAttr'], array(
				'content' => $this->checkbox($name, $box)
			));
		}

		$return .= $this->h->html->close();
		return $return;
	}

	function select($name, $options, $args = array(), $attr = array()) {

	}
	
	function submit($name, $args = array(), $attr = array()) {
		$attr = arrayExtend($attr, array(
			'type' => 'submit',
			'name' => $name,
			'class' => ''
		));
		if(isset($args['value'])) {
			$attr['value'] = $args['value'];
		} else {
			$attr['value'] = $name;
			$attr['name'] = slugify($attr['name']);
		}
		$attr['name'] = $this->name . '['.$attr['name'].']';
		$attr['class'] .= ' submit';
		
		return $this->h->html->open('input', $attr, array('selfClosing' => true));
	}
	
	function errors() {
		return '';
	}

	private function inlineErrors($data) {
		$errors = $data->getErrors();
		return $this->h->html->open('span', array('class' => array('inlineErrors')), array(
			'content' => $errors[0]
		));
	}
}

?>
